/* QAD_ProductStructureCostReport.p - Bill of Materials Cost Report           */
/* Copyright 1986-2011 QAD Inc., Santa Barbara, CA, USA.                      */
/* All rights reserved worldwide.  This is an unpublished work.               */
/* $Id:: QAD_ProductStructureCostReport.p 10571 2011-09-30 01:27:54Z jxx   $: */
/*                                                                            */
/* Report matches legacy bmpsrp01.p for use by QAD Reporting Framework.       */
/*                                                                            */

{mfsubdirs.i}
{{&US_BBI}mfdeclre.i}
{{&US_BBI}gplabel.i}

{com/qad/shell/report/dsReportRequest.i}
{com/qad/shell/report/ReportConstants.i}

/*============================================================================*/
/* ****************************  TEMP TABLES  ******************************* */
/*============================================================================*/

/* TEMP-TABLE DEFINITION BLOCK */

define temp-table tt_ps_mstr no-undo like ps_mstr
   field lvl                  as   character
   field um                   like pt_mstr.pt_um
   field batch_qty            like bom_mstr.bom_batch
   field batch_um             like bom_mstr.bom_batch_um
   field display_batch        like mfc_ctrl.mfc_logical
   field msg_desc             like msg_mstr.msg_desc
   field id_group_by_parent   as   integer
   field unique_id            as   integer
   index idx unique_id
.

define temp-table ttDescription no-undo
   field description          as   character
   field ref_unique_id        as   integer
   index idx ref_unique_id
.

define temp-table ttCategoryCost no-undo
   field level_label       as character
   field mtl               like sct_det.sct_mtl_tl
   field lbr               like sct_det.sct_lbr_tl
   field bdn               like sct_det.sct_bdn_tl
   field ovh               like sct_det.sct_ovh_tl
   field sub               like sct_det.sct_sub_tl
   field tot               like sct_det.sct_cst_tot
   field ref_unique_id     as integer
   index idx ref_unique_id
.

define temp-table tt_spt_det no-undo like spt_det
   field category       as character
   field spt_tot        like sct_det.sct_cst_tot
   field spt_xtd        like sct_det.sct_cst_tot
   field ref_unique_id  as integer
   index idx ref_unique_id
.

define temp-table ttReportOptions no-undo
   field newpage      like mfc_ctrl.mfc_logical
   field catelm       like mfc_ctrl.mfc_logical
   field formula_only like mfc_ctrl.mfc_logical
.

define temp-table ttReportConditions no-undo
   field part      like pt_mstr.pt_part
   field numlevels as   integer
   field eff_date  as   date
   field site      like si_mstr.si_site
   field csset     like sct_det.sct_sim
.

define dataset dsReportResults for tt_ps_mstr,ttDescription, ttCategoryCost,
               tt_spt_det, ttReportOptions, ttReportConditions.

/*============================================================================*/
/* *****************************  MAIN BLOCK  ******************************* */
/*============================================================================*/
define input parameter runReport    as logical no-undo.
define input parameter reportHandle as handle  no-undo.
define input parameter dataset      for dsReportRequest.
define output parameter dataset-handle phReportResults.

{com/qad/shell/report/reporting.i}
{com/qad/shell/report/reports/QAD_HelperFunctions.i}

define variable vhDS as handle no-undo.
define workfile pswkfl no-undo
   field psrecid     as recid
   field pscode      like ps_ps_code
   field psstart     like ps_start
   field psqtype     like ps_qty_type
   field qty_per     like ps_qty_per
   field qty_per_b   like ps_qty_per_b
   field net_qty     like ps_qty_per
.

empty temp-table tt_ps_mstr         no-error.
empty temp-table ttDescription      no-error.
empty temp-table ttCategoryCost     no-error.
empty temp-table tt_spt_det         no-error.
empty temp-table ttReportOptions    no-error.
empty temp-table ttReportConditions no-error.

for first ttReportRequest no-lock:

   vhDS = dataset dsReportResults:handle.
   run FillMetaData in reportHandle(
      vhDS, "QAD_ProductStructureCostReport.meta.xml").

   run SetReportMetaData (input reportHandle).

   if runReport then do:
      run RunReport
         (output dataset-handle phReportResults).
   end.

end.

PROCEDURE SetReportMetaData:

   define input parameter  ipReportHandle as handle.

   run SetFieldMetaParameter in ipReportHandle("ttReportOptions",
         "catelm", "DataFormat",getLabel("ELEMENT/CATEGORY")).

   run SetFieldMetaParameter in ipReportHandle ("ttReportOptions",
      "newpage", "DataFormat", getLabel("YES/NO")).

   run SetFieldMetaParameter in ipReportHandle ("ttReportOptions",
      "formula_only", "DataFormat", getLabel("YES/NO")).

   run SetFieldMetaParameter in ipReportHandle("ttReportConditions",
         "site", "DefaultValue", global_site).

   for first si_mstr no-lock where si_mstr.si_domain = global_domain
      and si_site = global_site:
   end.
   if available si_mstr
   then do:
      run SetFieldMetaParameter in ipReportHandle("ttReportConditions",
         "csset", "DefaultValue", si_cur_set).
   end.

END PROCEDURE. /* PROCEDURE ModifyMetaData */

/* DATA RETRIEVING LOGIC BLOCK */
PROCEDURE RunReport:

   define output parameter dataset-handle phReportResults.

   /* RETRIEVE THE DATA FROM DATABASE */
   define variable queryString   as character no-undo.
   define variable hMainQuery    as handle    no-undo.
   define query    MainQuery     for pt_mstr.
   define variable transtype     as character initial "BM" no-undo.
   define variable catelm        like mfc_ctrl.mfc_logical no-undo.
   define variable site          like si_mstr.si_site no-undo.
   define variable eff_date      as date no-undo.
   define variable csset         like sct_det.sct_sim no-undo.
   define variable numlevels     as integer no-undo.
   define variable formula_only  like mfc_ctrl.mfc_logical no-undo.
   define variable count_comp    as integer initial 0 no-undo.
   define variable parent_id     as integer initial 0 no-undo.
   /*Element*/
   define variable usr_val       as character extent 5 no-undo.
   define variable usr_elm       like sc_mstr.sc_element extent 5 no-undo.
   define variable l_gl_std      like mfc_ctrl.mfc_logical no-undo.
   define variable comp          like ps_mstr.ps_comp no-undo.
   define variable bom_code      like pt_mstr.pt_bom_code no-undo.
   define variable level         as integer no-undo.
   define variable maxlevel      as integer no-undo.
   define variable yield_pct     like pt_mstr.pt_yield no-undo.
   define variable batch_qty     like bom_mstr.bom_batch no-undo.
   define variable batch_um      like bom_mstr.bom_batch_um no-undo.
   define variable parent        like ps_mstr.ps_par no-undo.
   define variable um            like pt_mstr.pt_um no-undo.
   define variable phantom       like mfc_ctrl.mfc_logical no-undo.
   define variable iss_pol       like pt_mstr.pt_iss_pol no-undo.
   define variable lvl           as character no-undo.
   define variable dpart         like pt_mstr.pt_part no-undo.
   define variable l_linked      like mfc_ctrl.mfc_logical no-undo.
   define variable des           as character extent 10 no-undo.
   define variable des_temp      as character extent 10 no-undo.
   define variable des_temp_count as integer initial 0 no-undo.
   define variable par_qty       like ps_mstr.ps_qty_per no-undo.
   define variable spt_tot       like sct_det.sct_cst_tot no-undo.
   define variable spt_xtd       like sct_det.sct_cst_tot no-undo.
   define variable joint_code    like wo_mstr.wo_joint_type no-undo.
   define variable joint_type    like wo_mstr.wo_joint_type no-undo.
   define variable joint_label   like lngd_det.lngd_translation no-undo.
   define variable i             as integer no-undo.
   define variable j             as integer no-undo.
   define variable k             as integer no-undo.
   define variable m             as integer no-undo.
   define variable record        as integer extent 100 no-undo.
   define variable scrp_pct      like ps_mstr.ps_scrp_pct no-undo.
   define variable dingbats      as character initial "temp!@#$" no-undo.
   define buffer ptmstr for pt_mstr.
   define buffer pt_mstr1 for pt_mstr.
   /*category*/
   define variable mtl_tl        like sct_det.sct_mtl_tl no-undo.
   define variable lbr_tl        like sct_det.sct_lbr_tl no-undo.
   define variable bdn_tl        like sct_det.sct_bdn_tl no-undo.
   define variable ovh_tl        like sct_det.sct_ovh_tl no-undo.
   define variable sub_tl        like sct_det.sct_sub_tl no-undo.
   define variable total_tl      like sct_det.sct_cst_tot no-undo.
   define variable mtl_tot       like mtl_tl no-undo.
   define variable lbr_tot       like lbr_tl no-undo.
   define variable bdn_tot       like bdn_tl no-undo.
   define variable ovh_tot       like ovh_tl no-undo.
   define variable sub_tot       like sub_tl no-undo.
   define variable total_ll      like total_tl no-undo.
   define variable mtl_ext       like mtl_tl no-undo.
   define variable lbr_ext       like sub_tl no-undo.
   define variable bdn_ext       like bdn_tl no-undo.
   define variable ovh_ext       like ovh_tl no-undo.
   define variable sub_ext       like sub_tl no-undo.
   define variable total_ext     like total_tl no-undo.

   assign
      hMainQuery           = query MainQuery:handle
      catelm               = IsTrueValue("ttReportOptions",
                                 "catelm", false)
      formula_only         = IsTrueValue("ttReportOptions",
                                 "formula_only", false)
      site                 = GetFilterValue("ttReportConditions",
                                 "site", global_site)
      eff_date             = GetDateFilterValue("ttReportConditions",
                                 "eff_date", TODAY)
      csset                = GetFilterValue("ttReportConditions",
                                 "csset", "")
      numlevels            = Integer(GetFilterValue("ttReportConditions",
                                 "numlevels","")).

   /*Validate site*/
   for first si_mstr where si_mstr.si_domain = global_domain
                     and   si_site           = site no-lock:
   end.
   if not available si_mstr
   then do:
      /* SITE DOES NOT EXIST */
      {{&US_BBI}pxmsg.i &MSGNUM=708 &ERRORLEVEL=3}
      return.
   end. /* IF NOT available si_mstr */
   if si_db <> global_db
   then do:
      /* SITE IS NOT ASSIGNED TO THIS DOMAIN */
      {{&US_BBI}pxmsg.i &MSGNUM=6251 &ERRORLEVEL=3}
      return.
   end. /* IF si_db <> global_db */

   /*Validate costset*/
   if csset = ""
   then do:
      /* BLANK NOT ALLOWED */
      {{&US_BBI}pxmsg.i &MSGNUM=40 &ERRORLEVEL=3}
      return.
   end. /* IF csset = "" */

   for first cs_mstr where cs_mstr.cs_domain = global_domain
               and cs_set = csset no-lock:
   end.
   if not available cs_mstr
   then do:
      /* COST SET DOES NOT EXIST */
      {{&US_BBI}pxmsg.i &MSGNUM=5407 &ERRORLEVEL=3}
      return.
   end. /* IF NOT AVAILABLE cs_mstr */
   create ttReportOptions. /*used for ui main report*/

   if catelm
   then do:
   /*By Element*/
      for each lngd_det no-lock where lngd_dataset = "sc_mstr"
            and lngd_key1 = "" and lngd_key2 = ""
            and lngd_key3 = "" and lngd_field = "sc_category"
            and lngd_lang = global_user_lang:
         usr_val[integer(lngd_key4)] = lngd_translation.
         usr_elm[integer(lngd_key4)] = substring(lngd_translation,1,3).
      end.
      /* RECOGNIZE SITE LINKS FOR GL COST WHEN A GL
         STANDARD COST SET IS SPECIFIED */
      /*l_gl_std*/
      /* CHECK IF THE COST SET ENTERED IS OF TYPE GL AND STANDARD METHOD */
      for first cs_mstr no-lock where cs_mstr.cs_domain = global_domain
            and  cs_set = csset:
         if cs_type = "GL" and cs_method = "STD"
         then do:
            l_gl_std = true.
         end.
      end. /* FOR FIRST CS_MSTR */

      /*Main Query*/
      queryString = "for each pt_mstr where pt_mstr.pt_domain = "
                  + quoter(global_domain).
      run AddAllConditions in reportHandle
         ("pt_mstr", input-output queryString).
      queryString = queryString + ":".

      hMainQuery:query-prepare(queryString).
      hMainQuery:query-open().
      hMainQuery:get-next().

      repeat while not hMainQuery:query-off-end:

         assign
         comp       = pt_mstr.pt_part
         maxlevel   = min(numlevels,99)
         yield_pct  = pt_mstr.pt_yield_pct
         level      = 1
         batch_qty  = 1.

         if pt_mstr.pt_bom_code <> "" then do:
            bom_code = pt_mstr.pt_bom_code.
         end.
         else do:
            bom_code = pt_mstr.pt_part.
         end.
         for first ptp_det no-lock  where ptp_det.ptp_domain = global_domain
               and ptp_part = pt_part
               and ptp_site = site:
         end.

         if available ptp_det then do:
            if ptp_bom_code <> ""
            then do:
               bom_code = ptp_bom_code.
            end.
            else do:
               bom_code = ptp_part.
            end.
            yield_pct = ptp_yld_pct.
         end.

         comp = bom_code.

         for first bom_mstr
            fields(bom_domain bom_batch bom_batch_um
                   bom_desc bom_formula bom_parent)
            where bom_mstr.bom_domain = global_domain
               and bom_parent = bom_code
               and (formula_only = no or bom_formula)
         no-lock:
         end. /* FOR FIRST bom_mstr */

         if not available bom_mstr then do:
            hMainQuery:get-next().
            next.
         end.
         else do:
            for first ps_mstr no-lock use-index ps_parcomp
               where ps_mstr.ps_domain = global_domain
                     and  ps_par = comp:
            end.
            if not available ps_mstr
            then do:
               hMainQuery:get-next().
               next.
            end.

            parent = pt_part.
            /* CHECK IF THIS ITEM IS LINKED TO ANOTHER SITE FOR THE COST  */
            l_linked = false.
            if l_gl_std then
            for first in_mstr no-lock
               where in_mstr.in_domain = global_domain
               and in_part = pt_part and in_site = site:
               if in_gl_cost_site <> in_site
               then do:
                  assign l_linked = true
                  des[10] = "  " + getTermLabel("GL_COST_SOURCE_SITE",12)
                  + ": " + string(in_gl_cost_site).
               end.
            end. /* FOR FIRST IN_MSTR */
            if l_linked then do:
            /*Cost Simulation Total Detail Table*/
               for first sct_det where sct_det.sct_domain = global_domain
                     and  sct_sim = csset and sct_part = pt_part
                     and sct_site = in_gl_cost_site no-lock:
               end.
            end.
            else do:
               for first sct_det where sct_det.sct_domain = global_domain
                     and sct_sim = csset and sct_part = pt_part
                     and sct_site = site no-lock:
               end.
            end.

            do i = 1 to 9:
               des[i] = "".
            end.

            des[1] = pt_desc1.
            des[2] = pt_desc2.

            if available sct_det and sct_cst_date <> ?
               then des[3] = string(year(sct_cst_date))
                              + "-" + string(month(sct_cst_date),"99")
                              + "-" + string(day(sct_cst_date),"99").

            if scrp_pct <> 0 or yield_pct <> 100
            then do:
               assign
                  des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%"
                  des[5] = "YIELD" + string(yield_pct) + "%".
            end.
            for first bom_mstr no-lock
               where bom_mstr.bom_domain = global_domain
               and bom_parent = pt_part:
            end.

            if available bom_mstr then do:
               batch_qty = bom_batch.
               batch_um  = bom_batch_um.
            end.
            par_qty = 1.

            /*create description for previous tt_ps_mstr*/
            if count_comp = 0 /* the first one */
            then do:
               /* clear the description */
               des_temp_count = 0.
               do m = 1 to 10:
                  des_temp[m] = "".
               end.
            end. /*if count_comp =0*/
            else do:
               /* not the first record */
               if des_temp_count <> 0
               then do:
                  do m =1 to des_temp_count:
                     create ttDescription.
                     ttDescription.description = des_temp[m].
                     ttDescription.ref_unique_id = count_comp.
                  end.
                  des_temp_count = 0. /* clear description */
               end.
            end. /* else do */
            /* create description  end */

            create tt_ps_mstr.
            buffer-copy ps_mstr to tt_ps_mstr no-error.
            parent_id = parent_id + 1.
            count_comp = count_comp + 1.
            assign
               tt_ps_mstr.lvl                = getTermLabel("PARENT",6)
               tt_ps_mstr.ps_comp            = parent
               tt_ps_mstr.unique_id          = count_comp
               tt_ps_mstr.ps_qty_per         = ?
               tt_ps_mstr.ps_qty_type        = ?
               tt_ps_mstr.um                 = ?
               tt_ps_mstr.ps_ps_code         = ?
               tt_ps_mstr.id_group_by_parent = parent_id.

            if transtype = "FM" then do:
               assign tt_ps_mstr.ps_qty_per = ?
                      tt_ps_mstr.ps_qty_type = "".
               if batch_qty <> 0 and batch_qty <> 1
               then do:
                  des[7] = getTermLabel("BATCH_QTY",9) + ": "
                           + string(batch_qty)
                           + " " + batch_um.
               end.
            end.

            if available ptp_det then do:
               joint_type = ptp_joint_type.
            end.
            else do:
               joint_type = pt_joint_type.
            end.
            if joint_type <> "" then do:
               /* Numeric ps_joint_type returns alpha code, label */
               {us/gp/gplngn2a.i &file     = ""wo_mstr""
                  &field    = ""wo_joint_type""
                  &code     = joint_type
                  &mnemonic = joint_code
                  &label    = joint_label}
               des[8] = joint_label.
            end.

            do k = 1 to 7:
               do j = 1 to 7:
                  if des[j] = "" then do:
                     do i = j to 8:
                        des[i] = des[i + 1].
                     end.
                  end.
               end.
            end.

            if available sct_det then do:
               i = -1.
               for each spt_det no-lock
                  where spt_det.spt_domain = global_domain
                     and spt_site = sct_site
                     and spt_sim  = sct_sim
                     and spt_part = sct_part
               break by spt_site by spt_sim by spt_part
               by spt_pct_ll by spt_cst_tl descending by spt_element:

                  i = min(8, i + 1).

                  spt_tot = spt_cst_tl + spt_cst_ll.
                  spt_xtd = par_qty * (spt_cst_tl + spt_cst_ll).
                  if(i >= 1) then do:
                     des_temp_count = des_temp_count + 1.
                     des_temp[des_temp_count] = des[i].
                  end.

                  create tt_spt_det.
                  buffer-copy spt_det to tt_spt_det no-error.
                  assign
                     tt_spt_det.category =
                              usr_elm[integer(truncate(spt_det.spt_pct_ll,0))]
                     tt_spt_det.spt_tot = spt_tot
                     tt_spt_det.spt_xtd =spt_xtd
                     tt_spt_det.ref_unique_id = count_comp.
                  if last-of(spt_det.spt_part) then do:
                     do j = i + 1 to 0:
                        if des[j] <> "" then do:
                           des_temp_count = des_temp_count + 1.
                           des_temp[des_temp_count] = des[j].
                        end.
                     end.
                  end. /*last-of spt_part*/
               end. /*for each spt_det end*/
            end. /*if available sct_det end*/

            /* IF THIS PARENT IS LINKED DISPLAY THE GL COST SITE */
            if l_linked then do:
               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = des[10].
            end.

            /* IF THIS PARENT IS LINKED DISPLAY THE LINKED COST AND GO TO THE */
            /* NEXT ITEM, DO NOT DISPLAY ITS COMPONENTS COST.                 */
            if l_linked then do:
               hMainQuery:get-next().
               next.
            end.
            repeat:
               l_linked = false.

               if l_gl_std then
               for first in_mstr
                  fields( in_domain in_site in_gl_cost_site)
                  where in_mstr.in_domain = global_domain
                     and  in_part = comp and in_site = site no-lock:

                  if in_gl_cost_site <> in_site then do:
                     l_linked = true.
                  end.
               end. /* FOR FIRST IN_MSTR */

               if (not available ps_mstr) or (l_linked) then do:
                  repeat:
                     level = level - 1.
                     if level < 1 then leave.
                     for first ps_mstr no-lock
                        where recid(ps_mstr) = record[level]:
                     end.
                     comp = ps_mstr.ps_par.
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock no-error.
                     if available ps_mstr then do:
                        leave.
                     end.
                  end.
               end. /*if not available ps_mstr*/
               if level < 1 then leave.

               if eff_date = ? or (eff_date <> ? and
                  (ps_mstr.ps_start = ? or ps_mstr.ps_start <= eff_date)
                  and (ps_mstr.ps_end = ? or eff_date <= ps_mstr.ps_end))
               then do:

                  assign um = ""
                     iss_pol = no
                     phantom = no
                     dpart = ps_mstr.ps_comp
                     bom_code = ps_mstr.ps_comp
                     yield_pct = 100
                     batch_qty = 1.

                  do i = 1 to 9:
                     des[i] = "".
                  end.

                  for first ptmstr where ptmstr.pt_domain = global_domain
                        and ptmstr.pt_part = ps_mstr.ps_comp no-lock:
                  end.
                  if available ptmstr then do:
                     assign um = ptmstr.pt_um
                        des[1] = ptmstr.pt_desc1
                        des[2] = ptmstr.pt_desc2
                        iss_pol = ptmstr.pt_iss_pol
                        phantom = ptmstr.pt_phantom
                        yield_pct = ptmstr.pt_yield_pct
                        bom_code = if ptmstr.pt_bom_code <> ""
                        then ptmstr.pt_bom_code else ptmstr.pt_part.

                     for first ptp_det no-lock
                        where ptp_det.ptp_domain = global_domain
                           and ptp_part = ptmstr.pt_part
                           and ptp_site = site:
                     end.
                     if available ptp_det
                     then do:
                        assign
                           iss_pol = ptp_iss_pol
                           phantom = ptp_phantom
                           yield_pct = ptp_yld_pct.
                        if ptp_bom_code <> ""
                        then do:
                           bom_code = ptp_bom_code.
                        end.
                        else do:
                           bom_code = ptp_part.
                        end.
                     end.
                  end.

                  for first bom_mstr no-lock
                     where bom_mstr.bom_domain = global_domain
                        and bom_parent = ps_mstr.ps_comp:
                  end.
                  if available bom_mstr then do:
                     batch_qty = bom_batch.
                     batch_um  = bom_batch_um.
                     if not available ptmstr then do:
                        des[1] = bom_desc.
                        um     = bom_batch_um.
                     end.
                  end.

                  record[level] = recid(ps_mstr).
                  lvl = "......".
                  lvl = substring(lvl,1,min(level - 1,5)) + string(level).
                  if length(lvl) > 6
                     then lvl = substring(lvl,length(lvl) - 5,6).

                  for each pswkfl exclusive-lock:
                     delete pswkfl.
                  end.

                  create pswkfl.
                  assign
                     psrecid = recid(ps_mstr)
                     pscode = ps_mstr.ps_ps_code
                     psstart = ps_mstr.ps_start
                     psqtype = ps_mstr.ps_qty_type.
                  if transtype <> "BM" then do:
                     qty_per_b = qty_per_b + ps_mstr.ps_qty_per_b.
                  end.
                  net_qty = ps_mstr.ps_qty_per *
                        (100 / (100 - ps_mstr.ps_scrp_pct)).
                  qty_per = ps_mstr.ps_qty_per.

                  repeat:
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp
                        and ps_mstr.ps_comp = dpart no-lock.
                     if not available ps_mstr then do:
                        leave.
                     end.
                     record[level] = recid(ps_mstr).
                     if eff_date = ? or (eff_date <> ? and
                        (ps_mstr.ps_start = ? or
                         ps_mstr.ps_start <= eff_date)
                        and (ps_mstr.ps_end = ? or
                           eff_date <= ps_mstr.ps_end)) then do:
                        for first pswkfl where pscode = ps_mstr.ps_ps_code
                           and psstart = ps_mstr.ps_start
                           and psqtype = ps_mstr.ps_qty_type:
                        end.
                        if not available pswkfl then do:
                           create pswkfl.
                           assign
                              pscode = ps_mstr.ps_ps_code
                              psstart = ps_mstr.ps_start
                              psqtype = ps_mstr.ps_qty_type.
                        end.
                        psrecid = recid(ps_mstr).
                        if transtype <> "BM" then do:
                           qty_per_b = qty_per_b + ps_mstr.ps_qty_per_b.
                        end.
                        qty_per = qty_per + ps_mstr.ps_qty_per.
                        net_qty = net_qty
                        + ps_mstr.ps_qty_per *
                        (100 / (100 - ps_mstr.ps_scrp_pct)).
                     end.
                  end.

                  for each pswkfl:
                     for first ps_mstr where recid(ps_mstr) = psrecid
                        no-lock:
                     end.

                     if available ptmstr then do:

                        l_linked = false.

                        if l_gl_std then
                        for first in_mstr
                           fields( in_domain in_site in_gl_cost_site)
                           where in_mstr.in_domain = global_domain
                           and in_part = ptmstr.pt_part
                           and in_site = site no-lock:

                           if in_gl_cost_site <> in_site then
                           assign
                              l_linked = true
                              des[10] = "  "
                                 + getTermLabel("GL_COST_SOURCE_SITE",12)
                                 + ": " + string(in_gl_cost_site).

                        end. /* FOR FIRST IN_MSTR */

                        if l_linked then do:
                           for first sct_det
                              where sct_det.sct_domain = global_domain
                              and sct_sim = csset
                              and sct_part = ptmstr.pt_part
                              and sct_site = in_gl_cost_site no-lock:
                           end.
                        end.
                        else do:
                           for first sct_det
                              where sct_det.sct_domain = global_domain
                              and sct_sim = csset
                              and sct_part = ptmstr.pt_part
                              and sct_site =  site no-lock:
                           end.
                        end.
                     end. /*if available ptmstr*/
                     else do: /*create a temporary 0.00 record*/
                        /*It is used in programs where the cost record
                          retrieval should be done literally.*/
                        for first sct_det exclusive-lock
                           where sct_det.sct_domain = global_domain
                           and  sct_sim = csset
                           and sct_part = dingbats
                           and sct_site = site:
                        end.

                        if not available sct_det then do:
                           create sct_det.
                           sct_det.sct_domain = global_domain.
                           assign
                              sct_sim       = csset
                              sct_part      = dingbats
                              sct_site      = site
                              sct_cst_date  = today
                              recno         = recid(sct_det).
                        end.

                        for each lngd_det no-lock
                           where lngd_dataset = "sc_mstr"
                           and lngd_key1 = ""
                           and lngd_key2 = ""
                           and lngd_key3 = ""
                           and lngd_field = "sc_category"
                           and lngd_lang = global_user_lang
                           and lookup(lngd_key4, "1,2,3,4,5") <> 0:
                           for first spt_det
                              where spt_det.spt_domain = global_domain
                              and spt_det.spt_site = sct_site
                              and spt_det.spt_sim = sct_sim
                              and spt_det.spt_part = sct_part
                              and truncate(spt_det.spt_pct_ll,0)
                              = decimal(lngd_key4) no-lock:
                           end.

                           if not available spt_det then do:
                              create spt_det.
                              spt_det.spt_domain = global_domain.
                              assign
                                 spt_det.spt_site = sct_site
                                 spt_det.spt_sim = sct_sim
                                 spt_det.spt_part = sct_part
                                 spt_det.spt_element
                                    = substring(lngd_translation,1,8)
                                 spt_det.spt_pct_ll = decimal(lngd_key4)
                                 recno = recid(spt_det).
                           end.
                        end.
                        /*gpsct08.i extend end */
                     end.

                     scrp_pct = 0.
                     if net_qty <> 0
                        then scrp_pct = 100 * (net_qty - qty_per) / net_qty.

                     if available sct_det and sct_cst_date <> ?
                        then des[3] = string(year(sct_cst_date))
                              + "-" + string(month(sct_cst_date),"99")
                              + "-" + string(day(sct_cst_date),"99").
                     if scrp_pct     <> 0
                        or yield_pct <> 100
                     then
                        assign
                           des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%"
                           des[5] = "YIELD" + string(yield_pct)      + "%".

                     if bom_code <> ps_mstr.ps_comp then do:
                        des[6] = "BOMCD" + bom_code.
                     end.

                     /*create description for previous tt_ps_mstr*/
                     if des_temp_count <> 0
                     then do:
                        do m =1 to des_temp_count:

                           create ttDescription.
                           ttDescription.description = des_temp[m].
                           ttDescription.ref_unique_id = count_comp.
                        end.
                        des_temp_count = 0. /* clear description */
                     end.
                     /*create description end*/

                     create tt_ps_mstr.
                     buffer-copy ps_mstr to tt_ps_mstr no-error.
                     count_comp = count_comp + 1.
                     assign
                        tt_ps_mstr.lvl = lvl
                        tt_ps_mstr.ps_qty_per = qty_per
                        tt_ps_mstr.um = um
                        tt_ps_mstr.unique_id = count_comp
                        tt_ps_mstr.id_group_by_parent = parent_id.

                     if transtype = "FM" then do:
                        assign
                           tt_ps_mstr.ps_qty_per = qty_per_b
                           tt_ps_mstr.ps_qty_type = ps_mstr.ps_qty_type.
                        if batch_qty <> 0 and batch_qty <> 1 then
                           des[7] = getTermLabel("BATCH_QTY",9) + ": "
                                    + string(batch_qty) + " "
                                    + batch_um.
                     end.

                     joint_type = "".
                     joint_label = "".
                     for first ptp_det no-lock
                        where ptp_det.ptp_domain = global_domain
                        and ptp_part = ps_mstr.ps_comp
                        and ptp_site = site:
                     end.
                     if available ptp_det then joint_type = ptp_joint_type.
                     else do:
                        for first pt_mstr1 no-lock
                           where pt_mstr1.pt_domain = global_domain
                           and pt_mstr1.pt_part = ps_mstr.ps_comp:
                        end.
                        if available pt_mstr1 then do:
                           joint_type = pt_mstr1.pt_joint_type.
                        end.
                     end.
                     if joint_type <> "" then do:
                        /* Numeric ps_joint_type returns alpha code, label*/
                        {us/gp/gplngn2a.i &file     = ""wo_mstr""
                           &field    = ""wo_joint_type""
                           &code     = joint_type
                           &mnemonic = joint_code
                           &label    = joint_label}
                        des[8] = joint_label.
                     end.

                     do j = 1 to 7:
                        do i = j + 1 to 8:
                           if des[i] = des[j] then do:
                              des[i] = "".
                           end.
                        end.
                     end.

                     do k = 1 to 7:
                        do j = 1 to 7:
                           if des[j] = "" then do:
                              do i = j to 8:
                                 des[i] = des[i + 1].
                              end.
                           end.
                        end.
                     end.

                     if available sct_det then do:
                        i = -1.
                        for each spt_det no-lock
                           where spt_det.spt_domain = global_domain
                           and spt_det.spt_site = sct_site
                           and spt_det.spt_sim  = sct_sim
                           and spt_det.spt_part = sct_part
                        break by spt_det.spt_site by spt_det.spt_sim
                        by spt_det.spt_part
                        by spt_det.spt_pct_ll
                        by spt_det.spt_cst_tl descending
                        by spt_det.spt_element:

                           i = min(8, i + 1).

                           spt_tot = spt_det.spt_cst_tl
                                           + spt_det.spt_cst_ll.
                           spt_xtd = qty_per * (spt_det.spt_cst_tl
                                             + spt_det.spt_cst_ll)
                           * (100 / (100 - scrp_pct)).

                           if i >= 1
                           then do:
                              des_temp_count = des_temp_count + 1.
                              des_temp[des_temp_count] = des[i].
                           end.
                           create tt_spt_det.
                           buffer-copy spt_det to tt_spt_det no-error.
                           assign
                              tt_spt_det.category =
                           usr_elm[integer(truncate(spt_det.spt_pct_ll,0))]
                              tt_spt_det.spt_tot = spt_tot
                              tt_spt_det.spt_xtd = spt_xtd
                              tt_spt_det.ref_unique_id = count_comp.

                           if last-of(spt_det.spt_part) then do:
                              do j = i + 1 to 9:
                                 if fill(" ",2) + des[j] <> "" then do:
                                    des_temp_count = des_temp_count + 1.
                                    des_temp[des_temp_count] = des[j].
                                 end.
                              end.
                           end. /* IF LAST-OF(spt_part)... */
                        end. /* FOR EACH spt_det */
                     end. /* IF AVAILABLE spt_det */

                     /* IF THIS PARENT IS LINKED DISPLAY THE GL COST SITE */
                     if l_linked then do:
                        des_temp_count = des_temp_count + 1.
                        des_temp[des_temp_count] = des[10].
                     end.
                  end. /*for each pswkfl*/

                  for first ps_mstr where recid(ps_mstr) = record[level]
                     no-lock:
                  end.

                  if level < maxlevel or maxlevel = 0 then do:
                     comp = bom_code.
                     level = level + 1.
                     for first ps_mstr use-index ps_parcomp
                         where ps_mstr.ps_domain = global_domain
                         and ps_mstr.ps_par = comp no-lock:
                     end.
                  end.
                  else do:
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock no-error.
                  end.

                  if available sct_det and sct_part = dingbats then do:
                     for each spt_det exclusive-lock
                        where spt_det.spt_domain = global_domain
                        and pt_mstr.pt_site = sct_site
                        and spt_det.spt_sim = sct_sim
                        and spt_det.spt_part = sct_part:
                        delete spt_det.
                     end.
                     delete sct_det.
                  end.
               end. /*if eff_date = ? line 585*/
               else do:
                  find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock no-error.
               end.
            end. /* Repeat end */
         end. /* IF AVAILABLE bom_mstr */

         hMainQuery:get-next().
      end. /* REPEAT QUERY */

      hMainQuery:query-close().

      /*create description for last tt_ps_mstr*/
      if des_temp_count <> 0
      then do:
         do m =1 to des_temp_count:
            create ttDescription.
            ttDescription.description = des_temp[m].
            ttDescription.ref_unique_id = count_comp.
         end.
         des_temp_count = 0. /* clear description */
      end.
      /*create description end*/

      /*Main QUery end*/
   end. /*By Element end*/

   else do:
   /*By Category*/

      /* RECOGNIZE SITE LINKS FOR GL COST WHEN A GL STANDARD
         COST SET IS SPECIFIED */
      /* CHECK IF THE COST SET ENTERED IS OF TYPE GL AND STANDARD METHOD */
      for first cs_mstr no-lock
         where cs_mstr.cs_domain = global_domain
         and  cs_set = csset:
            if cs_type = "GL" and cs_method = "STD"
            then do:
               l_gl_std = true.
            end.
      end. /* FOR FIRST CS_MSTR */

      /*Main Query*/
      queryString = "for each pt_mstr where pt_mstr.pt_domain = "
                  + quoter(global_domain).
      run AddAllConditions in reportHandle
         ("pt_mstr", input-output queryString).
      queryString = queryString + ":".

      hMainQuery:query-prepare(queryString).
      hMainQuery:query-open().
      hMainQuery:get-next().

      repeat while not hMainQuery:query-off-end:

         assign
            comp = pt_part
            bom_code = if pt_bom_code <> "" then pt_bom_code else pt_part
            maxlevel = min(numlevels,99)
            yield_pct = pt_yield_pct
            scrp_pct = 0
            level = 1.

         for first ptp_det no-lock
            where ptp_det.ptp_domain = global_domain
            and  ptp_part = pt_part
            and ptp_site = site:
         end.

         if available ptp_det
         then do:
            if ptp_bom_code <> ""
            then do:
               bom_code = ptp_bom_code.
            end.
            else do:
               bom_code = ptp_part.
            end.
            yield_pct = ptp_yld_pct.
         end.

         comp = bom_code.

         for first bom_mstr
            fields(bom_domain bom_batch bom_batch_um
                bom_desc bom_formula bom_parent)
            where bom_mstr.bom_domain = global_domain
            and bom_parent = bom_code
            and (formula_only = no or bom_formula) no-lock:
         end. /* FOR FIRST bom_mstr */

         if not available bom_mstr then do:
            hMainQuery:get-next().
            next.
         end.
         else do:

            for first ps_mstr no-lock
               use-index ps_parcomp
               where ps_mstr.ps_domain = global_domain
               and  ps_mstr.ps_par = comp:
            end.

            if not available ps_mstr
            then do:
               hMainQuery:get-next().
               next.
            end.

            parent = pt_part.

            /* CHECK IF THIS ITEM IS LINKED TO ANOTHER SITE FOR GL COST  */
            l_linked = false.
            if l_gl_std then
            for first in_mstr no-lock
               where in_mstr.in_domain = global_domain
               and in_part = pt_part
               and in_site = site:

               if in_gl_cost_site <> in_site
               then do:
                  assign
                     l_linked = true
                     des[8] = "  "
                        + getTermLabel("GL_COST_SOURCE_SITE",12)
                        + ": " + string(in_gl_cost_site).
               end.
            end. /* FOR FIRST IN_MSTR */

            if l_linked
            then do:
               for first sct_det
                  where sct_det.sct_domain = global_domain
                  and  sct_sim = csset
                  and sct_part = pt_part
                  and sct_site = in_gl_cost_site no-lock:
               end.
            end.
            else do:
               for first sct_det
                  where sct_det.sct_domain = global_domain
                  and  sct_sim = csset
                  and sct_part = pt_part
                  and sct_site = site no-lock:
               end.
            end.

            /* START DISPLAY */
            if available sct_det   then do:
            assign
               total_tl = sct_mtl_tl + sct_lbr_tl
                        + sct_bdn_tl + sct_sub_tl + sct_ovh_tl
               total_ll = sct_mtl_ll + sct_lbr_ll
                        + sct_bdn_ll + sct_sub_ll + sct_ovh_ll
               mtl_tot = sct_mtl_tl + sct_mtl_ll
               lbr_tot = sct_lbr_tl + sct_lbr_ll
               bdn_tot = sct_bdn_tl + sct_bdn_ll
               ovh_tot = sct_ovh_tl + sct_ovh_ll
               sub_tot = sct_sub_tl + sct_sub_ll
               des[2] = pt_desc2
               des[3] = "".
            end.
            else do:
            assign
               total_tl = 0
               total_ll = 0
               mtl_tot = 0
               lbr_tot = 0
               bdn_tot = 0
               ovh_tot = 0
               sub_tot = 0
               des[2] = pt_desc2
               des[3] = "".
            end.

            if available sct_det and sct_cst_date <> ?
            then do:
               if des[2] = "" then do:
                  des[2] = string(year(sct_cst_date))
                              + "-" + string(month(sct_cst_date),"99")
                              + "-" + string(day(sct_cst_date),"99").
               end.
               else do:
                  des[3] = string(year(sct_cst_date))
                              + "-" + string(month(sct_cst_date),"99")
                              + "-" + string(day(sct_cst_date),"99").
               end.
            end.

            assign      des[4] = ""
               des[5] = "".

            if scrp_pct <> 0 and yield_pct = 100
            then do:
               des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%".
            end.

            if scrp_pct = 0 and yield_pct <> 100
            then do:
               des[4] = des[4] + "YIELD" + string(yield_pct) + "%".
            end.

            if scrp_pct <> 0 and yield_pct <> 100
            then do:
               assign
                  des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%"
                  des[5] = "YIELD" + string(yield_pct) + "%".
            end.

            if des[3] = ""
            then do:
               assign
                  des[3] = des[4]
                  des[4] = des[5]
                  des[5] = "".
            end.

            for first bom_mstr no-lock
               where bom_mstr.bom_domain = global_domain
               and bom_parent = pt_part:
            end.

            if available bom_mstr
            then do:
               assign
                  batch_qty = bom_batch
                  batch_um  = bom_batch_um.
            end.

            /*create description for previous tt_ps_mstr*/
            if count_comp = 0 /* the first one */
            then do:
               /* clear the description */
               des_temp_count = 0.
               do m = 1 to 10:
                  des_temp[m] = "".
               end.
            end. /*if count_comp =0*/
            else do:
               /* not the first record */
               if des_temp_count <> 0
               then do:
                  do m =1 to des_temp_count:
                     create ttDescription.
                     ttDescription.description = des_temp[m].
                     ttDescription.ref_unique_id = count_comp.
                  end.
                  des_temp_count = 0. /* clear description */
               end.
            end. /* else do */
            /* create description  end */

            create tt_ps_mstr.
            buffer-copy ps_mstr to tt_ps_mstr no-error.
            count_comp = count_comp + 1.
            parent_id = parent_id + 1.
            assign
               tt_ps_mstr.lvl = getTermLabel("PARENT",6)
               tt_ps_mstr.ps_comp = parent
               tt_ps_mstr.unique_id = count_comp
               tt_ps_mstr.ps_qty_per = ?
               tt_ps_mstr.ps_qty_type = ?
               tt_ps_mstr.um = ?
               tt_ps_mstr.ps_ps_code = ?
               tt_ps_mstr.id_group_by_parent = parent_id.

            if transtype = "BM"
            then do:
            end.

            else do:
               if batch_qty <> 1
               then do:
                  tt_ps_mstr.batch_qty = batch_qty.
                  tt_ps_mstr.batch_um = batch_um.
                  tt_ps_mstr.display_batch = true.
               end.
            end. /* end of else do */

            des_temp_count = des_temp_count + 1.
            des_temp[des_temp_count] = pt_desc1.
            create ttCategoryCost.
            assign
               ttCategoryCost.level_label = getTermLabelRt("THIS_LEVEL",12)
               ttCategoryCost.tot = total_tl
               ttCategoryCost.ref_unique_id = count_comp.

            if available sct_det
            then do:
               assign
                  ttCategoryCost.mtl = sct_det.sct_mtl_tl
                  ttCategoryCost.lbr = sct_det.sct_lbr_tl
                  ttCategoryCost.bdn = sct_det.sct_bdn_tl
                  ttCategoryCost.ovh = sct_det.sct_ovh_tl
                  ttCategoryCost.sub = sct_det.sct_sub_tl.
            end.
            else do:
               assign
                  ttCategoryCost.mtl = 0
                  ttCategoryCost.lbr = 0
                  ttCategoryCost.bdn = 0
                  ttCategoryCost.ovh = 0
                  ttCategoryCost.sub = 0.
            end.

            des_temp_count = des_temp_count + 1.
            des_temp[des_temp_count] = des[2].
            create ttCategoryCost.
            assign
               ttCategoryCost.level_label = getTermLabelRt("LOWER_LEVEL",12)
               ttCategoryCost.tot = total_ll
               ttCategoryCost.ref_unique_id = count_comp.
            if available sct_det
            then do:
               assign
                  ttCategoryCost.mtl = sct_mtl_ll
                  ttCategoryCost.lbr = sct_lbr_ll
                  ttCategoryCost.bdn = sct_bdn_ll
                  ttCategoryCost.ovh = sct_ovh_ll
                  ttCategoryCost.sub = sct_sub_ll.
            end.
            else do:
               assign
                  ttCategoryCost.mtl = 0
                  ttCategoryCost.lbr = 0
                  ttCategoryCost.bdn = 0
                  ttCategoryCost.ovh = 0
                  ttCategoryCost.sub = 0.
            end.

            des_temp_count = des_temp_count + 1.
            des_temp[des_temp_count] = des[3].
            create ttCategoryCost.
            assign
               ttCategoryCost.level_label = getTermLabelRt("UNIT_TOTAL",12)
               ttCategoryCost.mtl = mtl_tot
               ttCategoryCost.lbr = lbr_tot
               ttCategoryCost.bdn = bdn_tot
               ttCategoryCost.ovh = ovh_tot
               ttCategoryCost.sub = sub_tot
               ttCategoryCost.ref_unique_id = count_comp.

            if available sct_det
            then do:
               ttCategoryCost.tot = sct_cst_tot.
            end.
            else do:
               ttCategoryCost.tot = 0.
            end.
            if des[4] <> ""
            then do:
               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = des[4].
            end.
            if des[5] <> ""
            then do:
               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = des[5].
            end.


            if bom_code <> parent
            then do:
               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = "BOMCD" + bom_code.
            end.

            joint_label = "".

            if available ptp_det
            then do:
               joint_type = ptp_joint_type.
            end.

            else do:
               joint_type = pt_joint_type.
            end.

            if joint_type <> ""
            then do:
               /* Numeric ps_joint_type returns alpha code, label */
               {{&us_gp}gplngn2a.i &file     = ""wo_mstr""
                  &field    = ""wo_joint_type""
                  &code     = joint_type
                  &mnemonic = joint_code
                  &label    = joint_label}

               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = joint_label.
            end. /* end of if joint_type*/

            /* IF THIS PARENT IS LINKED DISPLAY THE GL COST SITE */
            if l_linked
            then do:
               des_temp_count = des_temp_count + 1.
               des_temp[des_temp_count] = des[8].
            end.

            /* IF THIS PARENT IS LINKED DISPLAY THE LINKED COST AND GO TO THE */
            /* NEXT ITEM, DO NOT DISPLAY ITS COMPONENTS COST.                 */
            if l_linked
            then do:
               hMainQuery:get-next().
               next.
            end.

            repeat:

               l_linked = false.

               if l_gl_std
               then do:
                  for first in_mstr
                  fields( in_domain in_site in_gl_cost_site)
                     where in_mstr.in_domain = global_domain
                     and in_part = comp
                     and in_site = site no-lock:

                     if in_gl_cost_site <> in_site
                     then do:
                        l_linked = true.
                     end.
                  end. /* FOR FIRST IN_MSTR */
               end. /* end if l_gl_std*/

               if (not available ps_mstr) or (l_linked)
               then do:
                  repeat:
                     level = level - 1.
                     if level < 1 then leave.
                     for first ps_mstr
                        where recid(ps_mstr) = record[level] no-lock:
                     end.
                     comp = ps_mstr.ps_par.
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock no-error.
                     if available ps_mstr
                     then do:
                        leave.
                     end.
                  end.

               end. /*end  if not available or*/

               if level < 1 then leave.

               if eff_date = ? or (eff_date <> ? and
                  (ps_mstr.ps_start = ? or ps_mstr.ps_start <= eff_date)
                  and (ps_mstr.ps_end = ? or eff_date <= ps_mstr.ps_end))
               then do:
                  assign
                     des[1] = getTermLabel("ITEM_NOT_IN_INVENTORY",24)
                     des[2] = ""
                     des[3] = ""
                     um = ""
                     iss_pol = no
                     phantom = no
                     dpart = ps_mstr.ps_comp
                     bom_code = ps_mstr.ps_comp
                     batch_qty = 1
                     yield_pct = 100.

                  for first ptmstr
                     where ptmstr.pt_domain = global_domain
                     and ptmstr.pt_part = ps_mstr.ps_comp no-lock:
                  end.

                  if available ptmstr
                  then do:
                     assign
                        um = ptmstr.pt_um
                        des[1] = ptmstr.pt_desc1
                        des[2] = ptmstr.pt_desc2
                        iss_pol = ptmstr.pt_iss_pol
                        phantom = ptmstr.pt_phantom
                        yield_pct = ptmstr.pt_yield_pct.
                     if ptmstr.pt_bom_code <> ""
                     then do:
                        bom_code = ptmstr.pt_bom_code.
                     end.
                     else do:
                        bom_code = ptmstr.pt_part.
                     end.

                     for first ptp_det no-lock
                        where ptp_det.ptp_domain = global_domain
                        and ptp_part = ptmstr.pt_part
                        and ptp_site = site:
                     end.

                     if available ptp_det
                     then do:
                        assign
                           iss_pol = ptp_iss_pol
                           phantom = ptp_phantom
                           yield_pct = ptp_yld_pct.
                        if ptp_bom_code <> ""
                        then do:
                           bom_code = ptp_bom_code.
                        end.
                        else do:
                           bom_code = ptp_part.
                        end.
                     end.
                  end. /* end  if available ptmstr*/

                  for first bom_mstr no-lock
                     where bom_mstr.bom_domain = global_domain
                     and bom_parent = ps_mstr.ps_comp:
                  end.

                  if available bom_mstr
                  then do:
                     assign
                        batch_qty = bom_batch
                        batch_um  = bom_batch_um.

                     if not available ptmstr
                     then do:
                        assign
                           des[1] = bom_desc
                           um    = bom_batch_um.
                     end.
                  end. /*end if available bom_mstr*/

                  assign
                     record[level] = recid(ps_mstr)
                     lvl = "......"
                     lvl = substring(lvl,1,min(level - 1,5)) + string(level).

                  if length(lvl) > 6
                  then do:
                     lvl = substring(lvl,length(lvl) - 5,6).
                  end.

                  for each pswkfl exclusive-lock:
                     delete pswkfl.
                  end.

                  create pswkfl.
                  assign
                     psrecid = recid(ps_mstr)
                     pscode = ps_mstr.ps_ps_code
                     psstart = ps_mstr.ps_start
                     psqtype = ps_mstr.ps_qty_type.

                  if transtype <> "BM"
                  then do:
                     qty_per_b = qty_per_b + ps_mstr.ps_qty_per_b.
                  end.

                  if ps_mstr.ps_scrp_pct = 100
                  then do:
                     net_qty = 0.
                  end.

                  else do:
                     net_qty = ps_mstr.ps_qty_per
                        * (100 / (100 - ps_mstr.ps_scrp_pct)).
                  end.

                  qty_per = ps_mstr.ps_qty_per.

                  repeat:
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp
                        and ps_mstr.ps_comp = dpart no-lock no-error.

                     if not available ps_mstr then leave.

                     record[level] = recid(ps_mstr).

                     if eff_date = ? or (eff_date <> ? and
                        (ps_mstr.ps_start = ? or ps_mstr.ps_start <= eff_date)
                        and (ps_mstr.ps_end = ? or eff_date <= ps_mstr.ps_end))
                     then do:
                        for first pswkfl where pscode = ps_mstr.ps_ps_code
                           and psstart = ps_mstr.ps_start
                           and psqtype = ps_mstr.ps_qty_type:
                        end.

                        if not available pswkfl
                        then do:
                           create pswkfl.
                           assign
                              pscode = ps_mstr.ps_ps_code
                              psstart = ps_mstr.ps_start
                              psqtype = ps_mstr.ps_qty_type.
                        end.

                        psrecid = recid(ps_mstr).

                        if transtype <> "BM"
                        then do:
                           qty_per_b = qty_per_b + ps_mstr.ps_qty_per_b.
                        end.

                        qty_per = qty_per + ps_mstr.ps_qty_per.

                        if ps_mstr.ps_scrp_pct = 100
                        then do:
                           net_qty = 0.
                        end.
                        else do:
                           net_qty = net_qty + ps_mstr.ps_qty_per
                              * (100 / (100 - ps_mstr.ps_scrp_pct)).
                        end.
                     end. /* end if eff_date =? */
                  end. /* repeat  end */

                  for each pswkfl:
                     for first ps_mstr
                        where recid(ps_mstr) = psrecid no-lock:
                     end.

                     if available ptmstr
                     then do:
                        l_linked = false.

                        if l_gl_std then do:
                           for first in_mstr
                              fields(in_domain in_site in_gl_cost_site)
                              where in_mstr.in_domain = global_domain
                              and in_part = ptmstr.pt_part
                              and in_site = site no-lock:

                              if in_gl_cost_site <> in_site then
                                 assign
                                    l_linked = true
                                    des[8] = "  "
                                       + getTermLabel("GL_COST_SOURCE_SITE",12)
                                       + ": " + string(in_gl_cost_site).
                           end. /* FOR FIRST IN_MSTR */
                        end.
                        if l_linked
                        then do:
                           for first sct_det
                              where sct_det.sct_domain = global_domain
                              and sct_sim = csset
                              and sct_part = ptmstr.pt_part
                              and sct_site = in_gl_cost_site no-lock:
                           end.
                        end.
                        else do:
                           for first sct_det
                              where sct_det.sct_domain = global_domain
                              and sct_sim = csset
                              and sct_part = ptmstr.pt_part
                              and sct_site = site no-lock:
                           end.
                        end.
                     end. /* if available ptmstr*/
                     else do: /*create a temporary 0.00 record*/
                        /*It is used in programs where the cost record
                          retrieval should be done literally.*/
                        for first sct_det exclusive-lock
                           where sct_det.sct_domain = global_domain
                           and  sct_sim = csset
                           and sct_part = dingbats
                           and sct_site = site:
                        end.

                        if not available sct_det then do:
                           create sct_det.
                           sct_det.sct_domain = global_domain.
                           assign sct_sim       = csset
                                  sct_part      = dingbats
                                  sct_site      = site
                                  sct_cst_date  = today
                                  recno         = recid(sct_det).
                        end.

                        for each lngd_det no-lock
                           where lngd_dataset = "sc_mstr"
                           and lngd_key1 = ""
                           and lngd_key2 = ""
                           and lngd_key3 = ""
                           and lngd_field = "sc_category"
                           and lngd_lang = global_user_lang
                           and lookup(lngd_key4, "1,2,3,4,5") <> 0:
                           for first spt_det
                              where spt_det.spt_domain = global_domain
                              and spt_det.spt_site = sct_site
                              and spt_det.spt_sim = sct_sim
                              and spt_det.spt_part = sct_part
                              and truncate(spt_det.spt_pct_ll,0)
                              = decimal(lngd_key4) no-lock:
                           end.

                           if not available spt_det then do:
                              create spt_det. spt_det.spt_domain
                                       = global_domain.
                              assign
                                 spt_det.spt_site = sct_site
                                 spt_det.spt_sim = sct_sim
                                 spt_det.spt_part = sct_part
                                 spt_det.spt_element
                                    = substring(lngd_translation,1,8)
                                 spt_det.spt_pct_ll = decimal(lngd_key4)
                                 recno = recid(spt_det).
                           end.
                        end. /*gpsct08.i extend end */
                     end.

                     if available sct_det
                     then do:
                        assign
                           total_tl = sct_mtl_tl + sct_lbr_tl + sct_bdn_tl
                           + sct_sub_tl + sct_ovh_tl
                           total_ll = sct_mtl_ll + sct_lbr_ll + sct_bdn_ll
                           + sct_sub_ll + sct_ovh_ll
                           mtl_tot = sct_mtl_tl + sct_mtl_ll
                           lbr_tot = sct_lbr_tl + sct_lbr_ll
                           bdn_tot = sct_bdn_tl + sct_bdn_ll
                           ovh_tot = sct_ovh_tl + sct_ovh_ll
                           sub_tot = sct_sub_tl + sct_sub_ll.
                     end.
                     else do:
                        assign
                           total_tl = 0
                           total_ll = 0
                           mtl_tot = 0
                           lbr_tot = 0
                           bdn_tot = 0
                           ovh_tot = 0
                           sub_tot = 0.
                     end.

                     assign
                        mtl_ext = (mtl_tot * qty_per)
                        lbr_ext = (lbr_tot * qty_per)
                        bdn_ext = (bdn_tot * qty_per)
                        ovh_ext = (ovh_tot * qty_per)
                        sub_ext = (sub_tot * qty_per)
                        scrp_pct = 0.

                     if net_qty <> 0
                     then do:
                        scrp_pct = 100 * (net_qty - qty_per) / net_qty.
                     end.

                     if scrp_pct <> 100
                     then do:
                        assign
                           mtl_ext = mtl_ext * (100 / (100 - scrp_pct))
                           lbr_ext = lbr_ext * (100 / (100 - scrp_pct))
                           bdn_ext = bdn_ext * (100 / (100 - scrp_pct))
                           ovh_ext = ovh_ext * (100 / (100 - scrp_pct))
                           sub_ext = sub_ext * (100 / (100 - scrp_pct)).
                     end.

                     assign
                        total_ext = mtl_ext + lbr_ext
                                 + bdn_ext + sub_ext + ovh_ext
                        des[4] = ""
                        des[5] = "".

                     if scrp_pct <> 0 and yield_pct = 100
                     then do:
                        des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%".
                     end.
                     if scrp_pct = 0 and yield_pct <> 100
                     then do:
                        des[4] = des[4] + "YIELD" + string(yield_pct) + "%".
                     end.
                     if scrp_pct <> 0 and yield_pct <> 100
                     then do:
                        assign
                           des[4] = "SCRAP" + string(scrp_pct, ">>9.99") + "%"
                           des[5] = "YIELD" + string(yield_pct)      + "%".
                     end.

                     if available sct_det and sct_cst_date <> ?
                     then do:
                        des[3] = string(year(sct_cst_date))
                              + "-" + string(month(sct_cst_date),"99")
                              + "-" + string(day(sct_cst_date),"99").
                     end.

                     if des[2] = ""
                     then do:
                        assign
                           des[2] = des[3]
                           des[3] = "".
                     end.

                     if des[2] = des[3]
                     then do:
                        des[3] = "".
                     end.

                     if des[3] = ""
                     then do:
                        assign
                           des[3] = des[4]
                           des[4] = des[5]
                           des[5] = "".
                     end.

                     des[6] = "".

                     if bom_code <> ps_mstr.ps_comp
                     then do:
                        des[6] = "BOMCD" + bom_code.
                     end.

                     /*create description for previous tt_ps_mstr*/
                     if des_temp_count <> 0
                     then do:
                        do m =1 to des_temp_count:
                           create ttDescription.
                           ttDescription.description = des_temp[m].
                           ttDescription.ref_unique_id = count_comp.
                        end.
                        des_temp_count = 0. /* clear description */
                     end.
                     /*create description end*/

                     if transtype = "BM"
                     then do:
                        create tt_ps_mstr.
                        count_comp = count_comp + 1.
                        buffer-copy ps_mstr to tt_ps_mstr no-error.
                        assign
                           tt_ps_mstr.lvl = lvl
                           tt_ps_mstr.um = um
                           tt_ps_mstr.unique_id = count_comp
                           tt_ps_mstr.id_group_by_parent = parent_id.
                     end.
                     else do:
                        create tt_ps_mstr.
                        count_comp = count_comp + 1.
                        buffer-copy ps_mstr to tt_ps_mstr no-error.
                        assign
                           tt_ps_mstr.lvl = lvl
                           tt_ps_mstr.um = um
                           tt_ps_mstr.unique_id = count_comp
                           tt_ps_mstr.id_group_by_parent = parent_id.

                        if batch_qty <> 0 and batch_qty <> 1
                        then do:
                           tt_ps_mstr.batch_qty = batch_qty.
                           tt_ps_mstr.batch_um = batch_um.
                           tt_ps_mstr.display_batch = true.
                        end.
                        else do:
                        end.
                     end.

                     /* Display first level amounts */
                     des_temp_count = des_temp_count + 1.
                     des_temp[des_temp_count] = des[1].

                     create ttCategoryCost.
                     assign
                        ttCategoryCost.level_label
                           = getTermLabelRt("THIS_LEVEL",12)
                        ttCategoryCost.tot = total_tl
                        ttCategoryCost.ref_unique_id = count_comp.

                     if available sct_det
                     then do:
                     assign
                        ttCategoryCost.mtl = sct_mtl_tl
                        ttCategoryCost.lbr = sct_lbr_tl
                        ttCategoryCost.bdn = sct_bdn_tl
                        ttCategoryCost.ovh = sct_ovh_tl
                        ttCategoryCost.sub = sct_sub_tl.
                     end.

                     /*Display second level amounts. */
                     des_temp_count = des_temp_count + 1.
                     des_temp[des_temp_count] = des[2].

                     create ttCategoryCost.
                     assign
                        ttCategoryCost.level_label
                           = getTermLabelRt("LOWER_LEVEL",12)
                        ttCategoryCost.tot = total_ll
                        ttCategoryCost.ref_unique_id = count_comp.

                     if available sct_det
                     then do:
                        assign
                           ttCategoryCost.mtl = sct_mtl_ll
                           ttCategoryCost.lbr = sct_lbr_ll
                           ttCategoryCost.bdn = sct_bdn_ll
                           ttCategoryCost.ovh = sct_ovh_ll
                           ttCategoryCost.sub = sct_sub_ll.
                     end.
                     else do:
                        assign
                           ttCategoryCost.mtl = 0
                           ttCategoryCost.lbr = 0
                           ttCategoryCost.bdn = 0
                           ttCategoryCost.ovh = 0
                           ttCategoryCost.sub = 0.
                     end.

                     if des[3] = ""
                     then do:
                        assign
                           des[3] = des[4]
                           des[4] = des[5]
                           des[5] = "".

                        if des[3] = ""
                        then do:
                           assign
                              des[3] = des[5]
                              des[5] = "".
                        end.

                        if des[3] = ""
                        then do:
                           assign
                              des[3] = des[6]
                              des[6] = "".
                        end.
                     end.

                     /* Display totals */
                     des_temp_count = des_temp_count + 1.
                     des_temp[des_temp_count] = des[3].

                     create ttCategoryCost.
                     assign
                        ttCategoryCost.level_label
                           = getTermLabelRt("UNIT_TOTAL",12)
                        ttCategoryCost.mtl = mtl_tot
                        ttCategoryCost.lbr = lbr_tot
                        ttCategoryCost.bdn = bdn_tot
                        ttCategoryCost.ovh = ovh_tot
                        ttCategoryCost.sub = sub_tot
                        ttCategoryCost.ref_unique_id = count_comp.

                     if available sct_det
                     then do:
                        ttCategoryCost.tot = sct_cst_tot.
                     end.
                     else do:
                        ttCategoryCost.tot = 0.
                     end.

                     if des[4] = ""
                     then do:
                        assign
                           des[4] = des[6]
                           des[6] = "".
                     end.

                     /* Display extended totals */
                     des_temp_count = des_temp_count + 1.
                     des_temp[des_temp_count] = des[4].

                     create ttCategoryCost.
                     assign
                        ttCategoryCost.level_label
                           = getTermLabelRt("EXT_TOTAL",12)
                        ttCategoryCost.mtl = mtl_ext
                        ttCategoryCost.lbr = lbr_ext
                        ttCategoryCost.bdn = bdn_ext
                        ttCategoryCost.ovh = ovh_ext
                        ttCategoryCost.sub = sub_ext
                        ttCategoryCost.tot = total_ext
                        ttCategoryCost.ref_unique_id = count_comp.

                     if des[5] <> ""
                     then do:
                        des_temp_count = des_temp_count + 1.
                        des_temp[des_temp_count] = des[5].
                     end.

                     if des[6] <> ""
                     then do:
                        des_temp_count = des_temp_count + 1.
                        des_temp[des_temp_count] = des[6].
                     end.

                     /* IF THIS ITEM IS LINKED DISPLAY THE GL COST SITE */
                     if l_linked
                     then do:
                        des_temp_count = des_temp_count + 1.
                        des_temp[des_temp_count] = des[8].
                     end.

                     assign
                        joint_type = ""
                        joint_label = "".

                     for first ptp_det no-lock
                        where ptp_det.ptp_domain = global_domain
                        and ptp_part = ps_mstr.ps_comp
                        and ptp_site = site:
                     end.

                     if available ptp_det
                     then do:
                        joint_type = ptp_joint_type.
                     end.

                     else do:
                        for first pt_mstr1 no-lock
                           where pt_mstr1.pt_domain = global_domain
                           and pt_mstr1.pt_part = ps_mstr.ps_comp:
                        end.
                        if available pt_mstr1
                        then do:
                           joint_type = pt_mstr1.pt_joint_type.
                        end.
                     end.

                     if joint_type <> ""
                     then do:
                        /* Numeric ps_joint_type returns alpha code, label */
                        {{&us_gp}gplngn2a.i &file     = ""wo_mstr""
                           &field    = ""wo_joint_type""
                           &code     = joint_type
                           &mnemonic = joint_code
                           &label    = joint_label}

                        des_temp_count = des_temp_count + 1.
                        des_temp[des_temp_count] = joint_label.
                     end.

                     if (total_tl + total_ll = 0)
                        and available ptmstr
                        and ptmstr.pt_pm_code = "P"
                     then do:
                        for first msg_mstr no-lock
                           where msg_nbr = 55
                           and msg_lang = global_user_lang:
                        end.
                        if available msg_mstr
                        then do:
                           /*display*/
                           tt_ps_mstr.msg_desc=msg_mstr.msg_desc.
                        end.
                     end.
                  end. /*for each pswkfl*/

                  for first ps_mstr no-lock
                     where recid(ps_mstr) = record[level]:
                  end.

                  if level < maxlevel or maxlevel = 0
                  then do:
                     assign
                        comp = bom_code
                        level = level + 1.
                     for first ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock:
                     end.
                  end.
                  else do:
                     find next ps_mstr use-index ps_parcomp
                        where ps_mstr.ps_domain = global_domain
                        and ps_mstr.ps_par = comp no-lock no-error.
                  end.

                  if available sct_det and sct_part = dingbats
                  then do:
                     delete sct_det.
                  end.
               end.
               else do:
                  find next ps_mstr use-index ps_parcomp
                     where ps_mstr.ps_domain = global_domain
                     and ps_mstr.ps_par = comp no-lock no-error.
               end.
            end. /*end repeat: l_linked = false */
         end. /* IF AVAILABLE bom_mstr */
         hMainQuery:get-next().
      end. /* REPEAT QUERY */

      hMainQuery:query-close().
      /*Main QUery end*/

      /*create description for last tt_ps_mstr*/
      if des_temp_count <> 0
      then do:
         do m =1 to des_temp_count:
            create ttDescription.
            ttDescription.description = des_temp[m].
            ttDescription.ref_unique_id = count_comp.
         end.
         des_temp_count = 0. /* clear description */
      end. /*create description end*/
   end. /*By Category end*/
   global_site = site.

   delete object hMainQuery.
   phReportResults = dataset dsReportResults:handle.

END PROCEDURE.
